package cn.yunyichina.provider.hquery.service.impl;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.annotation.Resource;
import javax.imageio.ImageIO;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.common.utils.StringUtils;

import cn.yunyichina.provider.framework.data.SpringContextHandler;
import cn.yunyichina.provider.framework.dubbo.service.HisifaceService;
import cn.yunyichina.provider.framework.qiniu.QiniuService;
import cn.yunyichina.provider.hquery.config.Config;
import cn.yunyichina.provider.hquery.constant.FileType;
import cn.yunyichina.provider.hquery.dao.ReportImageDao;
import cn.yunyichina.provider.hquery.entity.ReportImage;
import cn.yunyichina.provider.hquery.thread.ReportListRunnable;
import cn.yunyichina.provider.hquery.vo.ExaminationVo;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.ResponseObject;
import cn.yunyichina.provider.iface.entity.hisiface.examination.ReportImageVo;
import cn.yunyichina.provider.iface.entity.hisiface.examination.ReportImageVoResponse;
import cn.yunyichina.utils.convert.JsonUtils;
import net.coobird.thumbnailator.Thumbnails;
/**
 * Created by chenjx on 2017/06/28 .
 * 报告功能
 */
@Service("reportServiceImpl")
public class ReportServiceImpl {
	
    private static final Logger logger = LoggerFactory.getLogger(ReportServiceImpl.class);
    
    @Resource
    private Properties yaml;
    
    @Autowired
    private ReportImageDao reportImageDao; //SpringContextHandler.getBean(ReportImageDao.class);
    
    /*
	    检查检查报告图片查询
	*/
	@SuppressWarnings("resource")
	public ResponseObject listReportImage(String data,String sessionId ,String appId) {
		
		logger.info("检查检查报告图片查询 getExamineImage data: "+data);
        ResponseObject response = new ResponseObject();
        ExaminationVo requestVo = JsonUtils.parseObject(data, ExaminationVo.class);
        
        if (StringUtils.isBlank(requestVo.getHospitalCode())
                ||StringUtils.isBlank(requestVo.getReportId())
                ||StringUtils.isBlank(requestVo.getReportType())){
            response.setResultCodeAndMessage("18002","hospitalCode,reportType,reportId不能为空");
            return response;
        }
        
        //结果集 检查检查报告图片信息
        List<ReportImageVoResponse> reportImageVoResponseList = null;
        //查数据库
        List<ReportImage> reportImgList = reportImageDao.selectByOrgCodeAndReportId(requestVo.getHospitalCode(), requestVo.getReportId());
        //数据库存在记录则不查调度中心
        if(reportImgList.size() != 0){
        	reportImageVoResponseList = new ArrayList<ReportImageVoResponse>();
        	for(ReportImage reportImage : reportImgList){
        		ReportImageVoResponse reportImageVoResponse = new ReportImageVoResponse();
        		reportImageVoResponse.setFileAddress(reportImage.getFileAddress());
        		reportImageVoResponse.setFileType(reportImage.getFileType());
        		reportImageVoResponseList.add(reportImageVoResponse);
        	}
        } else {
        	//检查检查报告图片查询
            try {
            	
            	ReportImageVo reportImageVo = new ReportImageVo();
            	reportImageVo.setHospitalCode(requestVo.getHospitalCode());
            	reportImageVo.setBranchCode(requestVo.getBranchCode());
            	reportImageVo.setPatCardType(requestVo.getPatCardType());
            	reportImageVo.setPatCardNo(requestVo.getPatCardNo());
            	reportImageVo.setReportId(requestVo.getReportId());
            	reportImageVo.setReportType(requestVo.getReportType());
                logger.info("调用调度中心开始");
                ResCommon<List<ReportImageVoResponse>> reportImageList  = HisifaceService.getHisifaceClient().getReportImage(reportImageVo);
                logger.info("调用调度中心结束");
                if (!"0".equals(reportImageList.getResultCode())){
                    logger.info("调用调度中心产生异常"+ reportImageList.getResultMessage());
                    response.setResultCodeAndMessage("18998", reportImageList.getResultMessage());
                    return response;
                }
                logger.info("调用调度中心返回 "+JsonUtils.toJsonString(reportImageList.getResultCode() + reportImageList.getResultMessage()));
                reportImageVoResponseList = reportImageList.getResult();
                
                if(CollectionUtils.isNotEmpty(reportImageVoResponseList)){
                	
                	byte[] bt = null;
                	ByteArrayInputStream byteArrayInputStream = null;
                	ByteArrayOutputStream os = null;
                	//图片下载链接
            		String bucketURL = Config.QINIU_REPORT_IMG_DOWNLOAD_URL;
            		//图片上传到七牛云服务器
                	for (ReportImageVoResponse reportImageVoResponse : reportImageVoResponseList) {
                		if(!"".equals(reportImageVoResponse.getFileContent())){
                			bt = Base64.decodeBase64(reportImageVoResponse.getFileContent().getBytes());
                    		byteArrayInputStream = new ByteArrayInputStream(bt);
                    		String fileName = requestVo.getHospitalCode() +"_report_" + requestVo.getReportType() + "_" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()).replace(" ", "_").replace(":", "_") + "." + reportImageVoResponse.getFileType();
                    		com.qiniu.http.Response res = null;
            	        	if(reportImageVoResponse.getFileType().equals(FileType.JPG)){
                    			//等比例图片压缩
            	        		logger.info("压缩开始=========== ");
                        		//byteArrayInputStream = saveMinPhotoes(byteArrayInputStream, reportImageVoResponse.getFileType(), 1509, 0.9d);
            	        		os = new ByteArrayOutputStream();  
            	    	        Thumbnails.of(byteArrayInputStream).size(1100, 750).toOutputStream(os);
            	    	        byteArrayInputStream = new ByteArrayInputStream(os.toByteArray());
            	    	        os.flush();
            	    	        os.close();
            	        		logger.info("压缩结束=========== ");
            	        	}
            				// 调用put方法上传
            	        	res = QiniuService.upload(byteArrayInputStream, fileName, Config.QINIU_BUCKET_FOR_REPORTIMG);
            	        	if(res.isOK() || res.statusCode == 614){
            	        		reportImageVoResponse.setFileAddress(bucketURL + fileName);
            	        	}else{
            	        		//失败再重复上传一次
            	        		res = QiniuService.upload(byteArrayInputStream, fileName, Config.QINIU_BUCKET_FOR_REPORTIMG);
            	        		if(res.isOK() || res.statusCode == 614){
            	        			reportImageVoResponse.setFileAddress(bucketURL + fileName);
            	        		}else{
            	        			logger.info("report_img_file_qiniu_upload_fail!");
            	        		}
                                //response.setResultCodeAndMessage("18001","上传失败");
                            }
            	        	byteArrayInputStream.close();
                		}
                	}
                }
                
            } catch (Exception ex) {
            	logger.error("检查检查报告图片查询异常：" + ex.toString());
                response.setResultCodeAndMessage("18999","系统异常");
                return  response;
            }
            
            if(reportImageVoResponseList != null){
    			//检查列表入库
				requestVo.setAppId(appId);
				logger.info(" listReportImage requestVo={}",new Object[]{JsonUtils.toJsonString(requestVo)});
    			Thread  listReportImageThread = new Thread(new ReportListRunnable(reportImageVoResponseList,requestVo));
    			listReportImageThread.start();
    		}
        }
        
        //清空fileContent字段的值，避免数据返回给前端过大
        List<ReportImageVoResponse> reportImageVoRespList = new ArrayList<ReportImageVoResponse>();
        for (ReportImageVoResponse reportImageVoResponse : reportImageVoResponseList) {
        	ReportImageVoResponse ReportImageVoResp = new ReportImageVoResponse();
        	ReportImageVoResp.setFileAddress(reportImageVoResponse.getFileAddress());
        	ReportImageVoResp.setFileType((reportImageVoResponse.getFileType()));
        	reportImageVoRespList.add(ReportImageVoResp);
        }
        
        response.setResultCodeAndMessageAndResult("0","成功",reportImageVoRespList);
        logger.info("【检查检查报告图片查询】结束, 返回结果=" + JsonUtils.toJsonString(response));
		return response;
	}
	
	/**
	 * 等比例压缩算法： 
	 * 算法思想：根据压缩基数和压缩比来压缩原图，生产一张图片效果最接近原图的缩略图
	 * @param srcURL 原图地址
	 * @param deskURL 缩略图地址
	 * @param comBase 压缩基数
	 * @param scale 压缩限制(宽/高)比例  一般用1：
	 * 当scale>=1,缩略图height=comBase,width按原图宽高比例;若scale<1,缩略图width=comBase,height按原图宽高比例
	 * @throws Exception
	 * @author shenbin
	 * @createTime 2014-12-16
	 * @lastModifyTime 2014-12-16
	 */
	public ByteArrayInputStream saveMinPhotoes(InputStream srcURL, String filetype, double comBase,
			double scale) throws Exception {
		
		Image src = ImageIO.read(srcURL);
		int srcHeight = src.getHeight(null);
		int srcWidth = src.getWidth(null);
		int deskHeight = 0;// 缩略图高
		int deskWidth = 0;// 缩略图宽
		double srcScale = (double) srcHeight / srcWidth;
		/**缩略图宽高算法*/
		if ((double) srcHeight > comBase || (double) srcWidth > comBase) {
			if (srcScale >= scale || 1 / srcScale > scale) {
				if (srcScale >= scale) {
					deskHeight = (int) comBase;
					deskWidth = srcWidth * deskHeight / srcHeight;
				} else {
					deskWidth = (int) comBase;
					deskHeight = srcHeight * deskWidth / srcWidth;
				}
			} else {
				if ((double) srcHeight > comBase) {
					deskHeight = (int) comBase;
					deskWidth = srcWidth * deskHeight / srcHeight;
				} else {
					deskWidth = (int) comBase;
					deskHeight = srcHeight * deskWidth / srcWidth;
				}
			}
		} else {
			deskHeight = srcHeight;
			deskWidth = srcWidth;
		}
		BufferedImage tag = new BufferedImage(deskWidth, deskHeight, BufferedImage.TYPE_3BYTE_BGR);
		tag.getGraphics().drawImage(src, 0, 0, deskWidth, deskHeight, null); //绘制缩小后的图
		
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		ImageIO.write(tag, filetype, byteArrayOutputStream);
		byte[] b = byteArrayOutputStream.toByteArray();
		ByteArrayInputStream ins = new ByteArrayInputStream(b);
		return ins;
	}
}
